/*
 * Copyright 2014-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sample.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler;
import org.springframework.session.Session;
import org.springframework.session.web.socket.config.annotation.AbstractSessionWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.server.RequestUpgradeStrategy;
import org.springframework.web.socket.server.standard.TomcatRequestUpgradeStrategy;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

// @formatter:off
// tag::class[]
@Configuration
@EnableScheduling
@EnableWebSocketMessageBroker
// 或者可以直接实现implements WebSocketMessageBrokerConfigure接口来开发
// AbstractSessionWebSocketMessageBrokerConfigurer 基于redis实现了session共享，可以保证服务器宕机session不失效
public class WebSocketConfig extends AbstractSessionWebSocketMessageBrokerConfigurer<Session> { // <1>

	/**
	 * endpoints就是连接点 websocket根据该url来进行webscoket连接.
	 * @param registry
	 */
	@Override
	protected void configureStompEndpoints(StompEndpointRegistry registry) { // <2>
//		// 配置 WebSocket 进入点，设置可以跨域, 及开启使用 SockJS，这些配置主要用配置连接端点，用于 WebSocket 连接
		registry.addEndpoint("/messages").withSockJS();
////		// 普通的stomp client进行连接
		RequestUpgradeStrategy upgradeStrategy = new TomcatRequestUpgradeStrategy();
		registry.addEndpoint("/messages")
				.setHandshakeHandler(new DefaultHandshakeHandler(upgradeStrategy))
				.setAllowedOrigins("*");
	}

	/**
	 * 配置消息代理选项
	 * @param registry
	 */
	@Override
	public void configureMessageBroker(MessageBrokerRegistry registry) {
		// 配置前缀, 有这些前缀的会路由到broker
		registry.enableSimpleBroker("/queue/", "/topic/")
			//配置stomp协议里, server返回的心跳
			.setHeartbeatValue(new long[]{10000L, 30000L})
			//配置发送心跳的scheduler
			.setTaskScheduler(new DefaultManagedTaskScheduler());

		// 配置使用外部broker
//		registry.enableStompBrokerRelay("/queue/", "/topic/")
//				.setRelayHost("外部mq的地址")
//				.setRelayPort("外部mq stomp的端口");

		// 配置前缀, 有这些前缀的会被到有@SubscribeMapping与@MessageMapping的业务方法拦截
		registry.setApplicationDestinationPrefixes("/app");
	}

}
// end::class[]
// @formatter:on
